/**
 *
 * Copyright by Samuel Castro & Joaquim Fonseca, 2011
 * All Rights Reserved
 *
 * NOTES:
 * Please do not redistribute this plugin without my permission
 * Plugin made for private use only
 *
 */
package com.SyDeck.sdCities;

import com.SySammy.SdBountyHunter.sdLaw;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;

/**
 *
 * @author Deck
 */
public class CityInfo {

    private static String accpath = "plugins/RPGmod/city/";
    private static final File accounts = new File(accpath + "info.txt");
    private static final File bounds = new File(accpath + "Bounds.txt");
    static final File Path = new File(accpath + "Path.txt");

    public void startup() {
        acc();
        bound();
        Path();
    }

    private void acc() {
        new File(accpath).mkdirs();
        if (!accounts.exists()) {
            try {
                accounts.createNewFile();
            } catch (IOException ex) {
            }
        }
    }

    private void Path() {
        new File(accpath).mkdirs();
        if (!Path.exists()) {
            try {
                Path.createNewFile();
            } catch (IOException ex) {
            }
        }
    }

    private void bound() {
        new File(accpath).mkdirs();
        if (!bounds.exists()) {
            try {
                bounds.createNewFile();
            } catch (IOException ex) {
            }
        }
    }

    public void MakeAccount(Player p, String aux) {
        String ply = p.getName();
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            prop.put(ply, aux + ",Building");
            prop.put(aux + "Limits", "0");
            prop.store(new FileOutputStream(accounts), null);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public String GetCityName(String p) {
        Properties prop = new Properties();
        String Key = p;
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String values = (prop.getProperty(Key));
            prop.store(new FileOutputStream(accounts), null);
            return values.split(",")[0];
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public String GetCityStatus(String p) {
        Properties prop = new Properties();
        String Key = p;
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String values = (prop.getProperty(Key));
            prop.store(new FileOutputStream(accounts), null);
            return values.split(",")[1];
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public int GetCityLimits(String City) {
        Properties prop = new Properties();
        String Key = City.toLowerCase() + "Limits";
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            int values = Integer.parseInt(prop.getProperty(Key));
            prop.store(new FileOutputStream(accounts), null);
            return values;
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return 0;
    }

    public void SetCityLimits(String City, String Limits, String world) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            prop.put(City.toLowerCase() + "Limits", Limits);
            prop.put(City.toLowerCase() + "L" + Limits, world);
            prop.store(new FileOutputStream(accounts), null);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public String GetLimits(String City, int Limit) {
        Properties prop = new Properties();
        String Key = City.toLowerCase() + "L" + Limit;
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String values = prop.getProperty(Key);
            prop.store(new FileOutputStream(accounts), null);
            return values;
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public void SetCityBounds(String City, String Bound, String Player) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(bounds);
            prop.load(in);
            prop.put(City.toLowerCase() + ";", ";" + Bound);
            prop.store(new FileOutputStream(bounds), null);
            removetrash(City.toLowerCase(), Player);
            addinfo(City.toLowerCase(), Player, "Owner");
            setCityInfo(City.toLowerCase(), Player, 1, 1, true);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public void DelCityBounds(String City) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(bounds);
            prop.load(in);
            prop.remove(City.toLowerCase() + ";");
            prop.store(new FileOutputStream(bounds), null);
            rpgBlockListener.poly.remove(City.toLowerCase());
            rpgBlockListener.Cities.remove(City.toLowerCase());
            rpgBlockListener.Citizens.remove(City.toLowerCase());
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public void removeCity(Player Player) {
        String City = GetCityName(Player.getName()).toLowerCase();
        String boundx = GetBounds(City);
        String[] aux = unPolygonFix(boundx);
        ArrayList Temp = getCityList(City);
        for (int x = 1; x < Temp.size(); x++) {
            removePlayer(Temp.get(x).toString(), Player);
        }
        for (int i = 0; i < aux.length; i = i + 3) {
            Location loc = new Location(Player.getWorld(), Double.parseDouble(aux[i]), Double.parseDouble(aux[i + 1]), Double.parseDouble(aux[i + 2]));
            loc.getBlock().setType(Material.AIR);
        }
        DelCityBounds(City);
        removetrash(City, Player.getName());
        sdLaw sdBH = new sdLaw();
        sdBH.CitiesRemovePrison(Player.getName());
    }

    public void removePlayer(String Player, Player Owner) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            prop.remove(Player);
            prop.store(new FileOutputStream(accounts), null);
            Player Paux = Owner.getServer().getPlayer(Player);
            if (Paux != null) {
                Paux.sendMessage(ChatColor.GOLD + "You have been removed from " + GetCityName(Owner.getName()));
            }
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public void cancelCity(Player Player) {
        String City = GetCityName(Player.getName()).toLowerCase();
        String aux1 = ";";
        for (int i = 1; i <= GetCityLimits(City); i++) {
            if (i == 1) {
                aux1 = aux1 + GetLimits(City, i);
            } else {
                aux1 = aux1 + "," + GetLimits(City, i);
            }
        }
        if (GetCityLimits(City) == 4) {
            String[] aux = unPolygonFix(aux1.split(";")[1]);
            for (int i = 0; i < aux.length; i = i + 3) {
                Location loc = new Location(Player.getWorld(), Double.parseDouble(aux[i]), Double.parseDouble(aux[i + 1]), Double.parseDouble(aux[i + 2]));
                loc.getBlock().setType(Material.AIR);
            }
        } else if ((GetCityLimits(City) > 0)) {
            String[] aux = aux1.split(";")[1].split(",");
            for (int i = 0; i < aux.length; i = i + 3) {
                Location loc = new Location(Player.getWorld(), Double.parseDouble(aux[i]), Double.parseDouble(aux[i + 1]), Double.parseDouble(aux[i + 2]));
                loc.getBlock().setType(Material.AIR);
            }
        }
        removetrash(City, Player.getName());
    }

    public String[] unPolygonFix(String bounds) {
        String[] bound = bounds.split(",");
        for (int i = 3; i < bound.length; i = i + 3) {
            if (bound[0].equalsIgnoreCase(bound[i])) {
                bound[i + 2] = "" + unFixInt(Integer.parseInt(bound[i + 2]), Integer.parseInt(bound[2]));
            } else if (bound[2].equalsIgnoreCase(bound[i + 2])) {
                bound[i] = "" + unFixInt(Integer.parseInt(bound[i]), Integer.parseInt(bound[0]));
            } else {
                bound[i + 2] = "" + unFixInt(Integer.parseInt(bound[i + 2]), Integer.parseInt(bound[2]));
                bound[i] = "" + unFixInt(Integer.parseInt(bound[i]), Integer.parseInt(bound[0]));
            }
        }
        return bound;
    }

    private int unFixInt(int x, int comp) {
        if (x > comp) {
            x--;
        } else {
            x++;
        }
        return x;
    }

    public ArrayList getCityList(String City) {
        Properties prop = new Properties();
        String Key = City.toLowerCase() + "List";
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String[] info = prop.getProperty(Key).split(",");
            prop.store(new FileOutputStream(accounts), null);
            ArrayList<String> Players = new ArrayList<String>();
            Players.addAll(Arrays.asList(info));
            return Players;
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public String GetBounds(String City) {
        Properties prop = new Properties();
        String Key = City.toLowerCase() + ";";
        try {
            FileInputStream in = new FileInputStream(bounds);
            prop.load(in);
            String info = prop.getProperty(Key);
            prop.store(new FileOutputStream(bounds), null);
            return info.split(";")[1];
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public void setCityInfo(String City, String Owner, int Level, int tHab, boolean first) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            prop.put(City.toLowerCase() + "Info", Owner + "," + Level + "," + tHab);
            if (first) {
                prop.put(City.toLowerCase() + "List", Owner);
            }
            prop.store(new FileOutputStream(accounts), null);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public String getCityInfo(String City) {
        Properties prop = new Properties();
        String Key = City.toLowerCase() + "Info";
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String info = prop.getProperty(Key);
            prop.store(new FileOutputStream(accounts), null);
            return info;
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public boolean exCity(String City) {
        Properties prop = new Properties();
        String Key = City.toLowerCase() + "Info";
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            if (prop.getProperty(Key) == null) {
                prop.store(new FileOutputStream(accounts), null);
                return false;
            }
            prop.store(new FileOutputStream(accounts), null);
            return true;
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return false;
    }

    public Set<Entry<Object, Object>> GetBounds() {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(bounds);
            prop.load(in);
            prop.store(new FileOutputStream(bounds), null);
            return prop.entrySet();

        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    private void removetrash(String City, String Player) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            for (int i = 1; i <= GetCityLimits(City.toLowerCase()); i++) {
                prop.remove(City.toLowerCase() + "L" + i);
            }
            prop.remove(City.toLowerCase() + "Limits");
            prop.remove(City.toLowerCase() + "Info");
            prop.remove(City.toLowerCase() + "List");
            prop.remove(City.toLowerCase() + "TP");
            prop.remove(Player);
            prop.store(new FileOutputStream(accounts), "");
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public void quitCity(String Player) {
        Properties prop = new Properties();
        try {
            String City = GetCityName(Player).toLowerCase();
            String[] aux = getCityInfo(City).split(",");
            setCityInfo(City, aux[0], Integer.parseInt(aux[1]), Integer.parseInt(aux[2]) - 1, false);
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String Temp = prop.getProperty(City + "List");
            String Tempf = Temp.split(",")[0];
            for (int i = 1; i < Temp.split(",").length; i++) {
                if (!Temp.split(",")[i].equalsIgnoreCase(Player)) {
                    Tempf = Tempf + "," + Temp.split(",")[i];
                }
            }
            prop.setProperty(City + "List", Tempf);
            rpgBlockListener.Citizens.get(City).remove(Player);
            prop.remove(Player);
            prop.store(new FileOutputStream(accounts), "");

        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public void giveOwner(String Owner, String Player) {
        changeInfo(Owner,"Citizen");
        changeInfo(Player,"Owner");
        String[] aux = getCityInfo(GetCityName(Owner)).split(",");
        setCityInfo(GetCityName(Owner), Player, Integer.parseInt(aux[1]), Integer.parseInt(aux[2]), false);
    }

    private void changeInfo(String Player, String Position) {
        Properties prop = new Properties();
        String City = GetCityName(Player);
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            prop.put(Player, City.toLowerCase() + "," + Position);
            prop.store(new FileOutputStream(accounts), null);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    private void addinfo(String City, String Player, String Position) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String temp = prop.getProperty(City.toLowerCase() + "List");
            prop.put(Player, City.toLowerCase() + "," + Position);
            prop.put(City.toLowerCase() + "List", temp + "," + Player);
            prop.store(new FileOutputStream(accounts), null);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public String getinfo(String Player) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String values = prop.getProperty(Player);
            prop.store(new FileOutputStream(accounts), null);
            return values;
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public boolean izOwner(String Player) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String values = prop.getProperty(Player).split(",")[1];
            prop.store(new FileOutputStream(accounts), null);
            if (values.equalsIgnoreCase("owner")) {
                return true;
            }
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return false;
    }

    public boolean hazCity(String Player) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String values = prop.getProperty(Player).split(",")[1];
            prop.store(new FileOutputStream(accounts), null);
            if (values.equalsIgnoreCase("citizen") || values.equalsIgnoreCase("owner")) {
                return true;
            }
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return false;
    }

    public void addCitizen(String Player, String Citizen) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String[] values = prop.getProperty(Player).split(",");
            String[] aux = getCityInfo(values[0]).split(",");
            prop.store(new FileOutputStream(accounts), null);
            addinfo(values[0], Citizen, "Citizen");
            setCityInfo(values[0], aux[0], Integer.parseInt(aux[1]), Integer.parseInt(aux[2]) + 1, false);
            rpgBlockListener.Citizens.get(values[0]).add(Citizen);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }

    public void PolygonFix(String City) {
        orderPolygon(City.toLowerCase());
        String L1 = GetLimits(City.toLowerCase(), 1);
        for (int i = 2; i <= 4; i++) {
            String Lcheck = GetLimits(City.toLowerCase(), i);
            if (L1.split(",")[0].equalsIgnoreCase(Lcheck.split(",")[0])) {
                SetCityLimits(City.toLowerCase(), "" + i, Lcheck.split(",")[0] + "," + Lcheck.split(",")[1] + "," + FixInt(Integer.parseInt(Lcheck.split(",")[2]), Integer.parseInt(L1.split(",")[2])));
            } else if (L1.split(",")[2].equalsIgnoreCase(Lcheck.split(",")[2])) {
                SetCityLimits(City.toLowerCase(), "" + i, FixInt(Integer.parseInt(Lcheck.split(",")[0]), Integer.parseInt(L1.split(",")[0])) + "," + Lcheck.split(",")[1] + "," + Lcheck.split(",")[2]);
            } else {
                SetCityLimits(City.toLowerCase(), "" + i, FixInt(Integer.parseInt(Lcheck.split(",")[0]), Integer.parseInt(L1.split(",")[0])) + "," + Lcheck.split(",")[1] + "," + FixInt(Integer.parseInt(Lcheck.split(",")[2]), Integer.parseInt(L1.split(",")[2])));
            }
        }
    }

    private int FixInt(int x, int comp) {
        if (x > comp) {
            x++;
        } else {
            x--;
        }
        return x;
    }

    private void orderPolygon(String City) {
        City = City.toLowerCase();
        for (int i = 1; i <= 4; i++) {
            for (int j = i + 1; j <= 4; j++) {
                if (Integer.parseInt(GetLimits(City, i).split(",")[0]) > Integer.parseInt(GetLimits(City, j).split(",")[0])) {
                    String aux = GetLimits(City, i);
                    SetCityLimits(City, "" + i, GetLimits(City, j));
                    SetCityLimits(City, "" + j, aux);
                } else if (Integer.parseInt(GetLimits(City, i).split(",")[0]) == Integer.parseInt(GetLimits(City, j).split(",")[0]) && Integer.parseInt(GetLimits(City, i).split(",")[2]) > Integer.parseInt(GetLimits(City, j).split(",")[2])) {
                    String aux = GetLimits(City, i);
                    SetCityLimits(City, "" + i, GetLimits(City, j));
                    SetCityLimits(City, "" + j, aux);
                }
            }
        }
        String aux = GetLimits(City, 3);
        SetCityLimits(City, "" + 3, GetLimits(City, 4));
        SetCityLimits(City, "" + 4, aux);
    }

    public boolean izRect(String City, String Player) {
        City = City.toLowerCase();
        if (!GetLimits(City, 1).split(",")[0].equals(GetLimits(City, 2).split(",")[0])) {
            return false;
        }
        if (!GetLimits(City, 2).split(",")[2].equals(GetLimits(City, 3).split(",")[2])) {
            return false;
        }
        if (!GetLimits(City, 3).split(",")[0].equals(GetLimits(City, 4).split(",")[0])) {
            return false;
        }
        if (Math.abs(Integer.parseInt(GetLimits(City, 1).split(",")[2]) - Integer.parseInt(GetLimits(City, 2).split(",")[2])) < 4 || (Math.abs(Integer.parseInt(GetLimits(City, 2).split(",")[0]) - Integer.parseInt(GetLimits(City, 3).split(",")[0])) < 4)) {
            return false;
        }
        return true;
    }

    public int getXsize(String City) {
        int x = Math.abs(Integer.parseInt(GetLimits(City, 1).split(",")[0]) - Integer.parseInt(GetLimits(City, 4).split(",")[0]));
        return x;
    }

    public int getYsize(String City) {
        int y = Math.abs(Integer.parseInt(GetLimits(City, 1).split(",")[2]) - Integer.parseInt(GetLimits(City, 2).split(",")[2]));
        return y;
    }

    public boolean canAdd(String City) {
        String temp = getCityInfo(City);
        if (Integer.parseInt(temp.split(",")[1]) * 6 > Integer.parseInt(temp.split(",")[2])) {
            return true;
        }
        return false;
    }

    public String CityNameByBlock(int x, int y) {
        if (!rpgBlockListener.Cities.isEmpty()) {
            for (int z = 0; z < rpgBlockListener.Cities.size(); z++) {
                //Polygon aux = poly.get(Cities.get(z));
                if (rpgBlockListener.poly.get(rpgBlockListener.Cities.get(z)).contains(x, y)) {
                    return rpgBlockListener.Cities.get(z);
                }
            }
        }
        return null;
    }

    public Location getloc(String City, Player P) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            String values = (prop.getProperty(City + "TP"));
            prop.store(new FileOutputStream(accounts), null);
            Location loc = new Location(P.getWorld(), Integer.parseInt(values.split(",")[0]), Integer.parseInt(values.split(",")[1]), Integer.parseInt(values.split(",")[2]));
            return loc;
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
        return null;
    }

    public void setloc(String City, Player P) {
        Properties prop = new Properties();
        try {
            FileInputStream in = new FileInputStream(accounts);
            prop.load(in);
            prop.put(City + "TP", (int) P.getLocation().getX() + "," + (int) P.getLocation().getY() + "," + (int) P.getLocation().getZ());
            prop.store(new FileOutputStream(accounts), null);
        } catch (Exception ex) {
            //log.log(Level.INFO, ex.getMessage());
        }
    }
}
//http://download.oracle.com/javase/1.4.2/docs/api/java/awt/Polygon.html

